home *** CD-ROM | disk | FTP | other *** search
/ Disc to the Future 2 / Disc to the Future Part II Programmer's Reference (Wayzata Technology)(6013)(1992).bin / MAC / THINKC / 4_0 / SNDLIST- / MAIN.C < prev    next >
Text File  |  1988-11-10  |  14KB  |  633 lines

  1. /*
  2.     Sound lister
  3.     "Main.c"
  4. */
  5.  
  6. #define GLOBALS
  7.  
  8. #include <EventMgr.h>
  9. #include <MenuMgr.h>
  10. #include <ResourceMgr.h>
  11. #include <StdFilePkg.h>
  12. #include <ToolboxUtil.h>
  13. #include "SndList.h"
  14.  
  15. /* ----- Activate/deactivate "Play" button ----------------------------- */
  16.  
  17. void UpdatePlay(window, active)
  18. register DocumentPeek window;
  19. register Boolean active;
  20. {
  21.     Point cell;
  22.  
  23.     cell.v = cell.h = 0;
  24.     active = active && LGetSelect(TRUE, &cell, window->list);
  25.     SetHilite(window, iPlay, active ? 0 : 255);
  26.     OutLine(window, iPlay, active ? patCopy : notPatCopy);
  27. }
  28.  
  29. /* ----- Identify window ----------------------------------------------- */
  30.  
  31. Boolean IsAppWindow(window)
  32. register WindowPeek window;
  33. {
  34.     if (!window)
  35.         return FALSE;
  36.     return window->windowKind >= 0;
  37. }
  38.  
  39. Boolean IsDAWindow(window)
  40. register WindowPeek window;
  41. {
  42.     if (!window)
  43.         return FALSE;
  44.     return window->windowKind < 0;
  45. }
  46.  
  47. /* ----- Adjust the cursor --------------------------------------------- */
  48.  
  49. void AdjustCursor(mouse, region)
  50. Point mouse;
  51. register RgnHandle region;
  52. {
  53.     register DocumentPeek frontmost;
  54.     register RgnHandle arrowRgn;
  55.     register RgnHandle iBeamRgn;
  56.     Rect iBeamRect;
  57.  
  58.     frontmost = (DocumentPeek)FrontWindow();
  59.     if ((!gInBackground) && (!IsDAWindow(frontmost))) {
  60.         arrowRgn = NewRgn();
  61.         iBeamRgn = NewRgn();
  62.         SetRectRgn(arrowRgn, 0x8000, 0x8000, 0x7FFE, 0x7FFE);
  63.         if (IsAppWindow(frontmost)) {
  64.             iBeamRect = (*frontmost->list)->rView;
  65.             SetPort(frontmost);
  66.             LocalToGlobal(&topLeft(iBeamRect));
  67.             LocalToGlobal(&botRight(iBeamRect));
  68.             RectRgn(iBeamRgn, &iBeamRect);
  69.         }
  70.         DiffRgn(arrowRgn, iBeamRgn, arrowRgn);
  71.         if (PtInRgn(mouse, iBeamRgn)) {
  72.             SetCursor(*GetCursor(ListCursor));
  73.             CopyRgn(iBeamRgn, region);
  74.         } else {
  75.             SetCursor(&arrow);
  76.             CopyRgn(arrowRgn, region);
  77.         }
  78.         DisposeRgn(arrowRgn);
  79.         DisposeRgn(iBeamRgn);
  80.     }
  81. }
  82.  
  83. /* ----- Activate/Deactivate events ------------------------------------ */
  84.  
  85. void DoActivate(window)
  86. register DocumentPeek window;
  87. {
  88.     if (IsAppWindow(window)) {
  89.         SetPort(window);
  90.         LActivate(TRUE, window->list);    /* Activate sounds list */
  91.         UpdatePlay(window, TRUE);        /* Activate "Play" button */
  92.         SetHilite(window, iLevel, 0);    /* Activate scroll bar */
  93.     }
  94. }
  95.  
  96. void DoDeactivate(window)
  97. register DocumentPeek window;
  98. {
  99.     if (IsAppWindow(window)) {
  100.         LActivate(FALSE, window->list);    /* Deactivate sounds list */
  101.         UpdatePlay(window, FALSE);        /* Deactivate "Play" button */
  102.         SetHilite(window, iLevel, 255);    /* Deactivate scroll bar */
  103.     }
  104. }
  105.  
  106. /* ----- Play a sound -------------------------------------------------- */
  107.  
  108. void Play(name)
  109. register unsigned char *name;
  110. {
  111.     register Handle h;
  112.  
  113.     if (h = Get1Resource('snd ', Extract(name))) {
  114.         HNoPurge(h);
  115.         HLock(h);
  116.         SndPlay(0L, h, FALSE);
  117.         HUnlock(h);
  118.         HPurge(h);
  119.     }
  120. }
  121.  
  122. /* ----- Play selected sounds ------------------------------------------ */
  123.  
  124. void PlaySnds(window)
  125. register DocumentPeek window;
  126. {
  127.     register ListHandle list;
  128.     Point myCell;                /* Current cell */
  129.     short  length;                /* Length of cell entry */
  130.     unsigned char name[300];    /* Name of sound resource */
  131.     short  xlevel;                /* To save sound level */
  132.     short  ref;
  133.     short  current;
  134.  
  135.     GetWTitle(window, name);
  136.     if ((ref = OpenResources(name, window->volume, ¤t)) == -1)
  137.         return;
  138.     list = window->list;
  139.     HideCursor();
  140.     GetSoundVol(&xlevel);
  141.     SetSoundVol(7 - GetCheck(window, iLevel));
  142.     myCell.v = myCell.h = 0;
  143.     while(LGetSelect(TRUE, &myCell, list)) {
  144.         length = sizeof(name);
  145.         LGetCell(name, &length, myCell, list);
  146.         Play(name);
  147.         LSetSelect(FALSE, myCell, list);    /* De-select the cell */
  148.         LNextCell(TRUE, TRUE, &myCell, list);
  149.     }
  150.     SetSoundVol(xlevel);
  151.     CloseResources(current, ref);
  152.     ShowCursor();
  153. }
  154.  
  155. /* ----- Handle modeless dialog ----------------------------------------- */
  156.  
  157. void DoDialog(window, item, modifier)
  158. register WindowPtr window;
  159. register short item;
  160. register short modifier;
  161. {
  162.     if (item == iPlay) {
  163.         UpdatePlay(window, FALSE);
  164.         if (modifier & optionKey) {
  165.             EditSnds(window);
  166.             UnloadSeg(EditSnds);
  167.         } else
  168.             PlaySnds(window);
  169.         UpdatePlay(window, TRUE);
  170.     }
  171. }
  172.  
  173. /* ----- Scroll bar filter for modeless dialog ------------------------- */
  174.  
  175. void ScrollDelay()
  176. {
  177.     long finalTicks;
  178.  
  179.     Delay(GetDblTime(), &finalTicks);
  180. }
  181.  
  182. pascal void ScrollAction(ch, part)
  183. register ControlHandle ch;
  184. register short part;
  185. {
  186.     register short value;
  187.  
  188.     value = GetCtlValue(ch);
  189.     switch(part) {
  190.         case inUpButton:
  191.             ScrollDelay();
  192.             value--;
  193.             break;
  194.         case inDownButton:
  195.             ScrollDelay();
  196.             value++;
  197.             break;
  198.         case inPageUp:
  199.             value = 0;
  200.             break;
  201.         case inPageDown:
  202.             value = 7;
  203.             break;
  204.     }
  205.     SetCtlValue(ch, value);
  206. }
  207.  
  208. void ScrollbarFilter(window, mouse)
  209. register WindowPtr window;
  210. Point mouse;
  211. {
  212.     Handle ch;
  213.     register short part;
  214.     short theType;
  215.     Handle theItem;
  216.     Rect theBox;
  217.  
  218.     if (IsAppWindow(window)) {
  219.         SetPort(window);
  220.         GlobalToLocal(&mouse);
  221.         part = FindControl(mouse, window, &ch);
  222.         GetDItem(window, iLevel, &theType, &theItem, &theBox);
  223.         /* The thumb is handled by the dialog manager */
  224.         if (part > 0 && ch == theItem && part != inThumb)
  225.             TrackControl(ch, mouse, ScrollAction);
  226.     }
  227. }
  228.  
  229. /* ----- Handle mouse click in window ---------------------------------- */
  230.  
  231. void DoContentClick(window, event)
  232. register DocumentPeek window;
  233. register EventRecord *event;
  234. {
  235.     Point mouse;
  236.  
  237.     if (IsAppWindow(window)) {
  238.         SetPort(window);
  239.         mouse = event->where;
  240.         GlobalToLocal(&mouse);
  241.         if (LClick(mouse, event->modifiers, window->list))
  242.             DoDialog(window, iPlay, event->modifiers);    /* Double click */
  243.         UpdatePlay(window, TRUE);
  244.     }
  245. }
  246.  
  247. /* ----- Handle key down event ----------------------------------------- */
  248.  
  249. void DoKeyDown(event)
  250. register EventRecord *event;
  251. {
  252.     register WindowPtr window;
  253.     register unsigned char key;
  254.  
  255.     if (IsAppWindow(window = FrontWindow())) {
  256.         key = event->message & charCodeMask;
  257.         if (!(event->modifiers & cmdKey)) {
  258.             if (key == '\r' || key == 0x03)        /* Return, Enter */
  259.                 DoDialog(window, iPlay, event->modifiers);
  260.             else
  261.                 SysBeep(1);
  262.         }
  263.     }
  264. }
  265.  
  266. /* ----- Get null event time ------------------------------------------- */
  267.  
  268. long GetSleep()
  269. {
  270.     register long sleep;
  271.     register WindowPtr frontmost;
  272.  
  273.     sleep = 0x7FFFFFFF;    /* MAXLONG */
  274.     if (!gInBackground) {
  275.         frontmost = FrontWindow();
  276.         if (IsAppWindow(frontmost))
  277.             sleep = GetCaretTime();
  278.     }
  279.     return sleep;
  280. }
  281.  
  282. /* ----- Adjust menus -------------------------------------------------- */
  283.  
  284. void AdjustMenus()
  285. {
  286.     register WindowPtr frontmost;
  287.     register MenuHandle menu;
  288.  
  289.     frontmost = FrontWindow();
  290.  
  291.     menu = GetMHandle(mFile);
  292.     if (gNumDocuments < maxOpenDocuments)
  293.         EnableItem(menu, iOpen);
  294.     else
  295.         DisableItem(menu, iOpen);
  296.     if (frontmost)
  297.         EnableItem(menu, iClose);
  298.     else
  299.         DisableItem(menu, iClose);
  300.  
  301.     menu = GetMHandle(mEdit);
  302.     if (IsDAWindow(frontmost)) {
  303.         EnableItem(menu, iUndo);
  304.         EnableItem(menu, iCut);
  305.         EnableItem(menu, iCopy);
  306.         EnableItem(menu, iClear);
  307.         EnableItem(menu, iPaste);
  308.     } else {
  309.         DisableItem(menu, iUndo);
  310.         DisableItem(menu, iCut);
  311.         DisableItem(menu, iCopy);
  312.         DisableItem(menu, iClear);
  313.         DisableItem(menu, iPaste);
  314.     }
  315. }
  316.  
  317. /* ----- Close window -------------------------------------------------- */
  318.  
  319. void DoCloseWindow(window)
  320. register DocumentPeek window;
  321. {
  322.     if (IsDAWindow(window))
  323.         CloseDeskAcc(((WindowPeek)window)->windowKind);
  324.     else
  325.         if (IsAppWindow(window)) {
  326.             LDispose(window->list);
  327.             DisposDialog(window);
  328.             gNumDocuments--;
  329.         }
  330. }
  331.  
  332. /* ----- Make a new sound list window ---------------------------------- */
  333.  
  334. pascal void DrawSndList(window, item)    /* Called by Dialog Manager */
  335. register DialogPtr window;
  336. register short item;
  337. {
  338.     short type;
  339.     Handle itemHdl;
  340.     Rect box;
  341.  
  342.     GetDItem(window, item, &type, &itemHdl, &box);
  343.     LUpdate(window->visRgn, ((DocumentPeek)window)->list);
  344.     FrameRect(&box);
  345. }
  346.  
  347. WindowPtr NewSndWindow(storage, fname, fvolume)
  348. DocumentPeek storage;
  349. char *fname;                    /* File name */
  350. short fvolume;                    /* Volume reference number */
  351. {
  352.     register WindowPtr window;
  353.     register ListHandle list;
  354.     register short i, k, length;
  355.     register Point myCell;
  356.     short current;                /* Current resource file */
  357.     short ref;                    /* New resource file */
  358.     Handle h;
  359.     Rect bounds, array;
  360.     short id;                    /* Resource id of sound resource */
  361.     ResType type;                /* Type of sound resource */
  362.     unsigned char info[300];    /* Name of sound resource */
  363.     unsigned char num[10];
  364.     short level;
  365.  
  366.     /* Create new window */
  367.  
  368.     CenterDialog('DLOG', rDialog, &Bounds);
  369.     if (!(window = GetNewDialog(rDialog, storage, -1L)))
  370.         return 0L;
  371.     SetWTitle(window, fname);
  372.     storage->volume = fvolume;
  373.     SetPort(window);
  374.     TextFont(1);
  375.     TextSize(9);
  376.     GetDItem(window, iList, &id, &h, &bounds);
  377.     SetDItem(window, iList, (short)id, &DrawSndList, &bounds);
  378.     InsetRect(&bounds, 1, 1);
  379.  
  380.     /* Create the list */
  381.  
  382.     if ((ref = OpenResources(fname, fvolume, ¤t)) == -1) {
  383.         CloseDialog(window);
  384.         return 0L;
  385.     }
  386.     array.top = array.left = 0;
  387.     array.bottom = Count1Resources('snd ');
  388.     array.right = 1;
  389.     CloseResources(current, ref);
  390.     if (array.bottom < 1) {
  391.         CloseDialog(window);
  392.         return 0L;
  393.     }
  394.  
  395.     bounds.right -= 15;
  396.     myCell.v = 12;
  397.     myCell.h = bounds.right - bounds.left;
  398.  
  399.     if (!(list = LNew(&bounds,&array,myCell,0,window,FALSE,FALSE,FALSE,TRUE))) {
  400.         CloseDialog(window);
  401.         return 0L;
  402.     }
  403.     storage->list = list;
  404.  
  405.     /* Fill the list with resource names */
  406.  
  407.     if ((ref = OpenResources(fname, fvolume, ¤t)) == -1) {
  408.         LDispose(list);
  409.         CloseDialog(window);
  410.         return 0L;
  411.     }
  412.  
  413.     myCell.v = myCell.h = 0;
  414.     i = 1;
  415.     SetResLoad(FALSE);    /* Don't load all the resource data now */
  416.     do {
  417.         if (h = Get1IndResource('snd ', i)) {
  418.             i++;
  419.             /* 0----+----1----+----2----+- */
  420.             /* 123456 1234567 xxxxxxxxxxxx */
  421.             GetResInfo(h, &id, &type, info + 14);
  422.             length = 15 + info[14];
  423.             for (k = 0; k <= 14; k++)
  424.                 info[k] = 0xCA;                        /* Hard space */
  425.             NumToString((long)id, num);
  426.             k = num[0];
  427.             BlockMove(num + 1, info + 6 - k, (long)k);
  428.             NumToString(SizeResource(h), num);
  429.             k = num[0];
  430.             BlockMove(num + 1, info + 14 - k, (long)k);
  431.         } else
  432.             length = 0;
  433.         LSetCell(info, length, myCell, list);
  434.     } while(LNextCell(TRUE, TRUE, &myCell, list));
  435.     SetResLoad(TRUE);
  436.     CloseResources(current, ref);
  437.  
  438.     GetSoundVol(&level);
  439.     SetCheck(window, iLevel, 7 - level);
  440.     LDoDraw(TRUE, list);
  441.     ShowWindow(window);
  442.  
  443.     return window;
  444. }
  445.  
  446. /* ----- Open a new file ----------------------------------------------- */
  447.  
  448. void DoNew()
  449. {    
  450.     register Ptr storage;
  451.     register WindowPtr window;
  452.     SFReply sfr;
  453.     Point where;
  454.  
  455.     GetDlogOrigin(getDlgID, &where, &Bounds);
  456.     SFGetFile(where, EmptyStr, 0L, -1, EmptyStr, 0L, &sfr);
  457.     if (sfr.good) {
  458.         if (storage = NewPtr(sizeof(DocumentRecord)))
  459.             if (window = NewSndWindow(storage, sfr.fName, sfr.vRefNum))
  460.                 gNumDocuments++;
  461.             else {
  462.                 DisposPtr(storage);
  463.                 Message(mSorry, 0);
  464.             }
  465.     }
  466. }
  467.  
  468. /* ----- Handle menu commands ------------------------------------------ */
  469.  
  470. void DoMenuCommand(menuResult)
  471. register long menuResult;
  472. {
  473.     register short menuID;
  474.     register short menuItem;
  475.     unsigned char name[256];
  476.  
  477.     menuID = HiWord(menuResult);
  478.     menuItem = LoWord(menuResult);
  479.     switch(menuID) {
  480.         case mApple:
  481.             switch(menuItem) {
  482.                 case iAbout:
  483.                     About();
  484.                     UnloadSeg(About);
  485.                     break;
  486.                 default:
  487.                     GetItem(GetMHandle(mApple), menuItem, name);
  488.                     OpenDeskAcc(name);
  489.                     break;
  490.             }
  491.             break;
  492.         case mFile:
  493.             switch(menuItem) {
  494.                 case iOpen:
  495.                     DoNew();
  496.                     break;
  497.                 case iClose:
  498.                     DoCloseWindow(FrontWindow());
  499.                     break;
  500.                 case iQuit:
  501.                     Terminate();
  502.                     break;
  503.             }
  504.             break;
  505.         case mEdit:
  506.             SystemEdit(menuItem-1);
  507.             break;
  508.     }
  509.     HiliteMenu(0);
  510. }
  511.  
  512. /* ----- Event handler ------------------------------------------------- */
  513.  
  514. void DoEvent(event)
  515. register EventRecord *event;
  516. {
  517.     #define suspendResumeMessage    1
  518.     #define resumeMask                1
  519.     #define mouseMovedMessage        0xFA
  520.  
  521.     register short part;
  522.     register unsigned char key;
  523.     WindowPtr window;
  524.     short item;
  525.  
  526.     /* Update filter for modeless dialog */
  527.     if (event->what == updateEvt &&
  528.             IsAppWindow(window = (WindowPtr)event->message))
  529.         UpdatePlay(window, window == FrontWindow());
  530.  
  531.     /* Scrollbar filter for modeless dialog */
  532.     if (event->what == mouseDown &&
  533.             (part = FindWindow(event->where, &window)) == inContent)
  534.         ScrollbarFilter(window, event->where);
  535.  
  536.     /* Modeless dialog event filter */
  537.     if (IsDialogEvent(event) && DialogSelect(event, &window, &item)) {
  538.         DoDialog(window, item, event->modifiers);
  539.         event->what = nullEvent;    /* Event handled by Dialog Manager */
  540.     }
  541.  
  542.     /* Now handle events */
  543.     switch(event->what) {
  544.         case mouseDown:
  545.             /*part = FindWindow(event->where, &window);*/
  546.             switch(part) {
  547.                 case inMenuBar:
  548.                     AdjustMenus();
  549.                     DoMenuCommand(MenuSelect(event->where));
  550.                     break;
  551.                 case inSysWindow:
  552.                     SystemClick(event, window);
  553.                     break;
  554.                 case inContent:
  555.                     if (window != FrontWindow())
  556.                         SelectWindow(window);
  557.                     else
  558.                         DoContentClick(window, event);
  559.                     break;
  560.                 case inDrag:
  561.                     DragWindow(window, event->where, &Bounds);
  562.                     break;
  563.                 case inGoAway:
  564.                     if (TrackGoAway(window, event->where))
  565.                         DoCloseWindow(window);
  566.                     break;
  567.                 }
  568.                 break;
  569.             case keyDown:
  570.             case autoKey:
  571.                 key = event->message & charCodeMask;
  572.                 if (event->modifiers & cmdKey) {
  573.                     if (event->what == keyDown) {
  574.                         AdjustMenus();
  575.                         DoMenuCommand(MenuKey(key));
  576.                     }
  577.                 } else
  578.                     DoKeyDown(event);
  579.                 break;
  580.             case activateEvt:
  581.                 window = (WindowPtr)event->message;
  582.                 if (event->modifiers & activeFlag)
  583.                     DoActivate(window);
  584.                 else
  585.                     DoDeactivate(window);
  586.                 break;
  587.             case app4Evt:
  588.                 if (((unsigned long)event->message >> 24) ==
  589.                         suspendResumeMessage) {
  590.                     window = FrontWindow();
  591.                     if (event->message & resumeMask) {
  592.                         gInBackground = FALSE;
  593.                         DoActivate(window);
  594.                     } else {
  595.                         gInBackground = TRUE;
  596.                         DoDeactivate(window);
  597.                     }
  598.                 }
  599.                 break;
  600.         }
  601. }
  602.  
  603. /* ----- Resume if system error ---------------------------------------- */
  604.  
  605. pascal void Crash()
  606. {
  607.     ExitToShell();
  608. }
  609.  
  610. /* ----- Main program -------------------------------------------------- */
  611.  
  612. void main()
  613. {
  614.     register RgnHandle cursorRgn;
  615.     EventRecord event;
  616.  
  617.     MaxApplZone();
  618.     Initialize();
  619.     UnloadSeg(Initialize);
  620.     DoNew();
  621.     cursorRgn = NewRgn();
  622.     do {
  623.         if (gHasWaitNextEvent)
  624.             WaitNextEvent(everyEvent, &event, GetSleep(), cursorRgn);
  625.         else {
  626.             SystemTask();
  627.             GetNextEvent(everyEvent, &event);
  628.         }
  629.         AdjustCursor(event.where, cursorRgn);
  630.         DoEvent(&event);
  631.     } while(TRUE);
  632. }
  633.